<?php
    /**
    * @package    Parser
    * @subpackage    Text
    */
    class Myext
    {
        /**
        * Upload image from form post or external image url
        * 
        * @param mixed $source $_FIELDS['upload_field'] or External url
        * @param string $saved_path Path to save image, end with slash /
        * @param string $file_name Name of file
        * @param array $params Config to save image
        * @return Upload
        */
        public static function uploadImage($source, $saved_path, $file_name, array $params = array()){
            Yii::import('ext.upload.Upload');
            if(!file_exists($saved_path)) mkdir($saved_path,0777,true);


            if(isset($source['size']) && is_numeric($source['size'])){
//                $upload = new Upload($source);
                $img = WideImage::load($source);
            }else{
                $img_copy = $saved_path.$file_name.'.jpg';
                $copied = copy($source, $img_copy);
//                $upload = new Upload($img_copy);
                $img = WideImage::load($source);
            }

//            $upload->file_new_name_body = $file_name; 
//            $upload->image_convert = 'jpg';
//            $upload->jpeg_quality = 90;
//            $upload->file_overwrite = TRUE;
//
//            //$upload->image_ratio            = TRUE;
//            //$upload->image_ratio_crop       = TRUE;
//            $upload->image_resize           = TRUE;
//            $upload->image_ratio_no_zoom_in = TRUE;
//
//
//            foreach($params as $key => $value){
//                $upload->$key           = $value;
//            }    
//            $upload->process($saved_path);
                
             $img = $img->resize($params['image_x'], $params['image_y'], 'inside', 'down');
             $img = $img->resizeCanvas($params['image_x'], $params['image_y'], 'center', 'center', $img->allocateColor(255, 255, 255));
             $img->saveToFile($saved_path.$file_name.'.jpg', 90);

            return $file_name.'.jpg';
        }


        /**
        * Trả về width, height của 1 external url file
        * 
        * @param string $img_url http://image.url/file.jpg
        * @param mixed $rang Chỉ chạy đến bytes
        * @param mixed $show_time thời gian chạy
        */
        public static function getWidthHeightImage($img_url, $rang = 666, $show_time = FALSE){
            if($show_time) $start = microtime(true);

            $curl = curl_init($img_url);
            if($rang) curl_setopt($curl, CURLOPT_HTTPHEADER, array("Range: bytes=0-{$rang}"));
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            $img = curl_exec($curl); 
            curl_close($curl);
            $im = @imagecreatefromstring($img);
            if($show_time){
                $stop = round(microtime(true) - $start, 5);
                $data['time'] = $stop;
            }
            $data['width'] = @imagesx($im);
            $data['height'] = @imagesy($im);
            return $data['width'] ? $data : NULL;
        }

        public static function saveContentImages($content, $saved_path, $params, $item_alias = ''){
            $content = trim($content);
            if(!$content) return;
            Yii::import('ext.simple_html_dom');

            $html = new simple_html_dom($content);
            $baseUrl = Yii::app()->request->getBaseUrl(TRUE);
            foreach($html->find('img') as $i => $img){
                //if(preg_match('{^http.+\.(jpg|jpeg|gif|png|bmp)(\?.+)?$}six', $img->src)/* && strpos($img->src, $baseUrl) === FALSE*/){
                if(preg_match('{^http.+$}six', $img->src)/* && strpos($img->src, $baseUrl) === FALSE*/){
                    $file_name = ($item_alias ? $item_alias.'_' : '').uniqid();
                    $size = self::getWidthHeightImage($img->src);
                    if(!$size) $size = self::getWidthHeightImage($img->src, 0);

                    if(($size && $size['width'] > 200 && $size['height'] > 150)){
                        $imgName = self::uploadImage($img->src, $saved_path, $file_name, $params);
                        $img->src = '/'.$saved_path.$imgName;

                    }
                    #$img->outertext = '<center>'.$img->outertext.'</center>';
                }
            }
            foreach($html->find('a') as $a){
                if(isset($a->find('img',0)->src) && strpos($a->find('img',0)->src, $baseUrl) !== FALSE){
                    $a->href = $a->find('img',0)->src;
                }
            }
            $content = $html->save();
            $html->clear();
            return $content;
        }

        public static function deleteDir($dir_path, $remove_dir = TRUE){
            if(file_exists($dir_path) && is_dir($dir_path)){
                if(substr($dir_path, -1) != '/') $dir_path .= '/';
                foreach(glob($dir_path.'*') as $v){
                    if(is_dir($v)){
                        self::deleteDir($v);
                    }
                    if(file_exists($v)) unlink($v);
                }
                if($remove_dir){
                    rmdir($dir_path); 
                }

            }
        }
        
        public static function deleteFile($file_path){
            if(file_exists($file_path) && !is_dir($file_path)){
                unlink($file_path);
            }
        }
        
        public static function createDir($dir_path){
            if(!file_exists($dir_path)){
                mkdir($dir_path,0777,true);
            }
            //chmod($dir_path, 0777);  
        }


        private static function _adj_tree(&$tree, $index, $item, $id_key, $parent_id_key, $children_key,  $ref = FALSE) {
            $i = $item[$id_key];
            $p = $item[$parent_id_key];
            $tree[$i] = isset($tree[$i]) ? $item + $tree[$i] : $item;
            if($ref){
                $tree[$p][$children_key][$index] = &$tree[$i];
            }else{
                $tree[$p][$children_key][] = &$tree[$i];
            }
        }

        public static function arrayToTree($data, $id_key = 'id', $parent_id_key = 'parent_id', $children_key = 'children', $parent_id_value = NULl, $ref = FALSE){
            if(empty($data)) return;
            $tree = array();
            foreach($data as $index => $item){
                self::_adj_tree($tree, $index , $item, $id_key, $parent_id_key, $children_key, $ref);
            }
            return $tree[$parent_id_value][$children_key];
        }

        public static function getRandomChar($num = 6){
            $charNumArr = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9');
            $n = count($charNumArr);
            $str = "";
            for($i=0; $i<$num; $i++) {
                $str .= $charNumArr[rand(0,$n-1)];
            }
            return $str;
        }


        public static function fetchRowsToTree(array $rows, $id_field = 'id', $parent_id_field = 'parent_id', $childs_field = 'childs', $ref = FALSE){;
            $data = array();
            $ref = array();
            foreach ($rows as & $row) {
                $ref[$row[$id_field]] = & $row;
                $row[$childs_field] = array();
            }

            foreach ($rows as $index => & $row){
                if (empty($row[$parent_id_field])){
                    if($ref) $data[$index] = & $row;
                    else     $data[] = & $row;
                }
                else{
                    if($ref) $ref[$row[$parent_id_field]][$childs_field][$index] = & $row;
                    else     $ref[$row[$parent_id_field]][$childs_field][] = & $row;
                }
            }
            return $data;
        }


        # Don%26#x27;t => Don't
        public static function html_entity_decode_utf8($string){
            $string = preg_replace('~&#x([0-9a-f]+);~ei', 'self::_code2utf(hexdec("\\1"))', $string);
            $string = preg_replace('~&#([0-9]+);~e', 'self::_code2utf(\\1)', $string);
            return $string;
        }
        private static function _code2utf($num){
            if ($num < 128) return chr($num);
            if ($num < 2048) return chr(($num >> 6) + 192) . chr(($num & 63) + 128);
            if ($num < 65536) return chr(($num >> 12) + 224) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
            if ($num < 2097152) return chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
            return '';
        }



        /*
        * Convert: Ng&#7855;m c&#225;c nh&#224; l&#227;nh => Ngáº¯m cÃ¡c nhÃ  lÃ£nh
        */ 
        public static function html_to_utf8($data){
            return preg_replace("/\\&\\#([0-9]{3,10})\\;/e", '$this->_html_to_utf8("\\1")', $data);
        }
        private function _html_to_utf8($data){
            if($data > 127){
                $i = 5;
                while(($i--) > 0){
                    if($data != ($a = $data % ($p = pow(64, $i)))){
                        $ret = chr(base_convert(str_pad(str_repeat(1, $i + 1), 8, "0"), 2, 10) + (($data - $a) / $p));
                        for($i; $i > 0; $i--){
                            $ret .= chr(128 + ((($data % pow(64, $i)) - ($data % ($p = pow(64, $i - 1)))) / $p));
                        }
                        break;
                    }
                }
            }else{
                $ret = "&#{$data};";
            }
            return $ret;
        }

        public static function char_limiter($str, $limit = 100, $end_char = '...'){
            $str_sub = mb_substr($str, 0, $limit, 'UTF-8');
            if (mb_strlen($str, 'UTF-8') > $limit){
                return $str_sub.$end_char;
            }
            else{
                return $str;
            }
        }
        public static function word_limit($string, $length, $ellipsis="...") {
            return (count($words = explode(' ', $string)) > $length) ? implode(' ', array_slice($words, 0, $length)) . $ellipsis : $string;
        }
        
        public static function numberFormat($number, $int = FALSE){
            if($int) return str_replace('.', '', $number);
            return number_format($number, 0, '', '.');
        }


        //echo distance('32.9697,-96.80322', '29.46786,-98.53506', "M") . " Miles<br>";
        //echo distance('32.9697,-96.80322', '29.46786,-98.53506', "K") . " Kilometers<br>";
        //echo distance('32.9697,-96.80322', '29.46786,-98.53506', "N") . " Nautical Miles<br>";
        public static function getDistanceFromLatLon($latlon1, $latlon2, $unit = 'k') {
            list($lat1, $lon1) = explode(',', $latlon1);
            list($lat2, $lon2) = explode(',', $latlon2);

            $theta = $lon1 - $lon2;
            $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
            $dist = acos($dist);
            $dist = rad2deg($dist);
            $miles = $dist * 60 * 1.1515;
            $unit = strtoupper($unit);

            if ($unit == "K") {
                return ($miles * 1.609344);
            } else if ($unit == "N") {
                return ($miles * 0.8684);
            } else {
                return $miles;
            }
        }

        
        //$file = "/folder/filename.ext";
        public static function force_download($file)
        {
            $ext = explode(".", $file);
            switch($ext[sizeof($ext)-1])
            {
                case 'jar': $mime = "application/java-archive"; break;
                case 'zip': $mime = "application/zip"; break;
                case 'jpeg': $mime = "image/jpeg"; break;
                case 'jpg': $mime = "image/jpg"; break;
                case 'jad': $mime = "text/vnd.sun.j2me.app-descriptor"; break;
                case "gif": $mime = "image/gif"; break;
                case "png": $mime = "image/png"; break;
                case "pdf": $mime = "application/pdf"; break;
                case "txt": $mime = "text/plain"; break;
                case "doc": $mime = "application/msword"; break;
                case "ppt": $mime = "application/vnd.ms-powerpoint"; break;
                case "wbmp": $mime = "image/vnd.wap.wbmp"; break;
                case "wmlc": $mime = "application/vnd.wap.wmlc"; break;
                case "mp4s": $mime = "application/mp4"; break;
                case "ogg": $mime = "application/ogg"; break;
                case "pls": $mime = "application/pls+xml"; break;
                case "asf": $mime = "application/vnd.ms-asf"; break;
                case "swf": $mime = "application/x-shockwave-flash"; break;
                case "mp4": $mime = "video/mp4"; break;
                case "m4a": $mime = "audio/mp4"; break;
                case "m4p": $mime = "audio/mp4"; break;
                case "mp4a": $mime = "audio/mp4"; break;
                case "mp3": $mime = "audio/mpeg"; break;
                case "m3a": $mime = "audio/mpeg"; break;
                case "m2a": $mime = "audio/mpeg"; break;
                case "mp2a": $mime = "audio/mpeg"; break;
                case "mp2": $mime = "audio/mpeg"; break;
                case "mpga": $mime = "audio/mpeg"; break;
                case "wav": $mime = "audio/wav"; break;
                case "m3u": $mime = "audio/x-mpegurl"; break;
                case "bmp": $mime = "image/bmp"; break;
                case "ico": $mime = "image/x-icon"; break;
                case "3gp": $mime = "video/3gpp"; break;
                case "3g2": $mime = "video/3gpp2"; break;
                case "mp4v": $mime = "video/mp4"; break;
                case "mpg4": $mime = "video/mp4"; break;
                case "m2v": $mime = "video/mpeg"; break;
                case "m1v": $mime = "video/mpeg"; break;
                case "mpe": $mime = "video/mpeg"; break;
                case "mpeg": $mime = "video/mpeg"; break;
                case "mpg": $mime = "video/mpeg"; break;
                case "mov": $mime = "video/quicktime"; break;
                case "qt": $mime = "video/quicktime"; break;
                case "avi": $mime = "video/x-msvideo"; break;
                case "midi": $mime = "audio/midi"; break;
                case "mid": $mime = "audio/mid"; break;
                case "amr": $mime = "audio/amr"; break;
                default: $mime = "application/force-download";
            }
            header('Content-Description: File Transfer');
            header('Content-Type: '.$mime);
            header('Content-Disposition: attachment; filename='.basename($file));
            header('Content-Transfer-Encoding: binary');
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
            header('Pragma: public');
            header('Content-Length: ' . filesize($file));
            ob_clean();
            flush();
            readfile($file);
        }
        
        
        public static function textDecode($s){
            $s = Myext::html_entity_decode_utf8($s); 
            $s = Myext::html_to_utf8($s);
            $s = html_entity_decode($s, ENT_COMPAT, 'UTF-8');
            $s = trim($s);
            return $s; 
        }
        
        public static function getRandomArray($array, $number = 1){
            $rand_keys = array_rand($array, $number);
            if($number > 1){
                $randomArray = array();
                foreach($rand_keys as $key){
                    $randomArray[] = $array[$key];    
                }
                return;
            }else{
                return $array[$rand_keys];    
            }
        }
        
        public static function print_array($arr){
            $str = '<ul>';
            if (is_array($arr)){
                foreach ($arr as $key=>$val){
                    $key = is_numeric($key) ? $key : "'{$key}'"; 
                    if (is_array($val)){
                        $str .= "<li>{$key} => array({self::print_array($val)}),</li>";
                    }else{
                        $val = is_numeric($val) ? $val : "'{$val}'";
                        $str .= "<li>{$key} => {$val},</li>";
                    }
                }
            }
            $str .= '</ul>';
            return $str;

        }
        
        public static function fixTinyMceUploadPath($path){
            // remove end slash
            if(substr($path, -1) == '/') $path = substr($path, 0, -1);
            // add begin slash
            if(substr($path, 0, 1) != '/') $path = '/'.$path;
            return $path;  
        }
        
        public static function mb_ucfirst_utf8($str) {
            $fc = mb_substr($str, 0, 1, 'UTF-8');
            $fcUpper = mb_convert_case($fc, MB_CASE_UPPER, 'UTF-8');
            $strWithoutFc = mb_substr($str, 1, mb_strlen($str, 'UTF-8')-1, 'UTF-8');
            $strWithoutFcLower = mb_convert_case($strWithoutFc, MB_CASE_LOWER, 'UTF-8'); 
            return $fcUpper.$strWithoutFcLower;
        }
        
    }
?>
